package xml.parserDOM;

import java.util.ArrayList;
import java.util.List;

public class Nodo<Tag> {

	    private Tag tag;
	    private String dato;
	    public List<Nodo<Tag>> children;

	    /**
	     * Contructor por defecto.
	     */
	    public Nodo() {
	        super();
	        children = new ArrayList<Nodo<Tag>>();
	    }

	    /**
	     * Contructor por paramentro
	     * @param data de tipo Tag
	     */
	    public Nodo(Tag data) {
	        this();
	        setTag(data);
	    }

	    /**
	     * retorna los hijos de nodo
		 * árbol está representado por un solo  Nodo<Tag> del tipo raiz cuyos hijos
		 * están representados por una lista <Nodo <T>>. Cada uno de
		 * Nodo <Tag> estos elementos en la lista puede tener hijos.
		 * Método devolverá los hijos de un <Tag> nodo.
	     * @return the children of Node<T>
	     */
	    public List<Nodo<Tag>> getChildren() {
	        if (this.children == null) {
	            return new ArrayList<Nodo<Tag>>();
	        }
	        return this.children;
	    }

	    /**
	     * Sets the children of a Node<T> object. See docs for getChildren() for
	     * more information.
	     * @param children the List<Node<T>> to set.
	     */
	    public void setChildren(List<Nodo<Tag>> children) {
	        this.children = children;
	    }

	    /**
	     * Retorna el numero de hijos de un nodo<Tag>
	     * @return l numero de hijos.
	     */
	    public int getNumberOfChildren() {
	        if (children == null) {
	            return 0;
	        }
	        return children.size();
	    }

	    /**
	     * Agrega un hijo para este Nodo<Tag>
	     * cuando agregar el primero, crea la intacia de ArrayList<Nodo<Tag>>

	     * @param child a Node<Tag> object.
	     */
	    public void addChild(Nodo<Tag> child) {
	        if (children == null) {
	            children = new ArrayList<Nodo<Tag>>();
	        }
	        children.add(child);
	    }

	    /**
	     * Inserta un Nodo<Tag> en una ubicacion especifica.
	     * @param index posición en la que se insertara el hijo
	     * @param child del Node<Tag> que se insertara .
	     * @throws IndexOutOfBoundsException if thrown.
	     */
	    public void insertChildAt(int index, Nodo<Tag> child) throws IndexOutOfBoundsException {
	        if (index == getNumberOfChildren()) {
	            // this is really an append
	            addChild(child);
	            return;
	        } else {
	            children.get(index); //just to throw the exception, and stop here
	            children.add(index, child);
	        }
	    }

	    /**
	     * Eliminar el Nodo<Tag> que corresponda al indice pasado por parametro
	     * @param index indice del elemento a borrar
	     * @throws IndexOutOfBoundsException if thrown.
	     */
	    public void removeChildAt(int index) throws IndexOutOfBoundsException {
	        children.remove(index);
	    }

	    public Tag getData() {
	        return this.tag;
	    }

	    public void setTag(Tag tag) {
	        this.tag = tag;
	    }

	    public String toString() {
	        StringBuilder sb = new StringBuilder();
	        sb.append("{").append(getData().toString()).append(",[");
	        int i = 0;
	        for (Nodo<Tag> e : getChildren()) {
	            if (i > 0) {
	                sb.append(",");
	            }
	            sb.append(e.getData().toString());
	            i++;
	        }
	        sb.append("]").append("}");
	        return sb.toString();
	    }

		public String getDato() {
			return dato;
		}

		public void setDato(String dato) {
			this.dato = dato;
		}

		public Tag getTag() {
			return tag;
		}



}
